package net.hanjava.swing;

import java.awt.Window;
import java.lang.ref.WeakReference;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.UIManager;

import sun.awt.AppContext;

public class Util {
	private static boolean swingInitializd = false;

	// do not instanciate
	private Util() {
	}

	public static void show(JComponent target, int x, int y, int w, int h) {
		ensureSwingInit();
		JFrame frame = new JFrame(target.getClass().toString());
		frame.setContentPane(target);
		frame.setBounds(x, y, w, h);
		frame.setVisible(true);
	}

	public static void show(JComponent target, int x, int y) {
		ensureSwingInit();
		JFrame frame = new JFrame(target.getClass().toString());
		frame.setContentPane(target);
		frame.pack();
		frame.setLocation(x, y);
		frame.setVisible(true);
	}

	public static void show(JComponent target) {
		ensureSwingInit();
		JFrame frame = new JFrame(target.getClass().toString());
		frame.setContentPane(target);
		frame.pack();
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);
	}

	public static void ensureSwingInit() {
		if (swingInitializd)
			return;
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		swingInitializd = true;
	}

	/**
	 * get all instances of <code>java.awt.Window</code> in current VM. only
	 * works for Sun JVM 1.6+
	 */
	private static List<Window> getAllWindowsFromStatic() throws Exception {
		Method method = Window.class.getDeclaredMethod("getAllWindows",
				new Class[0]);
		method.setAccessible(true);
		Object result = method.invoke(null, new Object[] {});
		return (List<Window>) result;
	}

	/**
	 * returns all instances of <code>java.awt.Window</code> in caller
	 * thread's <code>AppContext</code>. <code>AppContext</code> can be one
	 * or more(mostly for applets) per process. note) <code>AppContext</code>
	 * not a standard java API. it'll works on Sun JVM or it's variations.
	 */
	@SuppressWarnings("unchecked")
	private static List<Window> getAllWindowsFromAppContext() throws Exception {
		Object oRefs = AppContext.getAppContext().get(Window.class);
		List<WeakReference<Window>> refs = (List<WeakReference<Window>>) oRefs;
		List<Window> result = new ArrayList<Window>();
		for (WeakReference<Window> wr : refs) {
			Window w = wr.get();
			result.add(w);
		}
		return result;
	}

	public static List<Window> getAllWindows() {
		try {
			return getAllWindowsFromStatic();
		} catch (Exception e) {
			try {
				return getAllWindowsFromAppContext();
			} catch (Exception e1) {
				throw new RuntimeException(e1);
			}
		}
	}
}